package com.example.hszpad.net;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 数据包转换工具类
 * Created by XuXianglong on 2017/4/24.
 */

public class ProtocolPackageConvert {
    /**
     * 将数据包转化为字节数据
     *
     * @param p
     * @return
     */
    public static byte[] convertProtocolPackageToByteArray(ProtocolPackage p) {
        if (null == p) {
            return null;
        }
        List<Byte> byteList = new ArrayList<>();
        //类编号
        byteList.add((byte) p.getClassCode());
        //方法编号
        byteList.add((byte) p.getMethordNo());
        //是否返回
        byteList.add((byte) p.getNeedReturn());

        List<ParamObject> paramObjectList = p.getObjectList();
        if (null != paramObjectList && !paramObjectList.isEmpty()) {
            //对象数量
            byteList.add((byte) paramObjectList.size());
            for (ParamObject obj : paramObjectList) {
                //对象ID
                byteList.add((byte) obj.getId());

                Map<Integer, Integer> paramMap = obj.getParamList();
                if (null == paramMap || paramMap.isEmpty()) {
                    //参数数量
                    byteList.add((byte) 0);
                } else {
                    //参数数量
                    byteList.add((byte) paramMap.size());
                    for (Integer key : paramMap.keySet()) {
                        byte[] ids = convertParamIdToByteArray(key);
                        //参数编号
                        for (int i = 0; i < ids.length; i++) {
                            byteList.add(ids[i]);
                        }
                        //参数值
                        byteList.add((byte) ((int) paramMap.get(key)));
                    }
                }
            }
        } else {
            //对象数量
            byteList.add((byte) 0);
        }
        byte[] data = new byte[byteList.size()];
        for (int i = 0; i < byteList.size(); i++) {
            data[i] = byteList.get(i);
        }
        return data;
    }

    /**
     * 将字节数组转化为数据包
     *
     * @param byteArray
     * @return
     */
    public static ProtocolPackage convertByteArrayToProtocolPackage(byte[] byteArray) {
        if (null == byteArray || byteArray.length < 16) {
            return null;
        }
        int offset = 0;
        ProtocolPackage pack = new ProtocolPackage();
        pack.setClassCode(byteArray[offset]);
        offset += 1;
        pack.setMethordNo(byteArray[offset]);
        offset += 1;
        pack.setNeedReturn(byteArray[offset]);
        offset += 1;
        int objectCount = byteArray[offset];
        offset += 1;
        List<ParamObject> objectList = new ArrayList<>();
        ParamObject object;
        for (int i = 0; i < objectCount; i++) {
            object = new ParamObject();
            object.setId(byteArray[offset]);
            //
            offset += 1;
            int paramCount = byteArray[offset];
            offset += 1;
            Map<Integer, Integer> paramMap = new HashMap<>();
            for (int j = 0; j < paramCount; j++) {
                List<Byte> lstFieldValue = new ArrayList<>();
                byte value = byteArray[offset];
                while (((value & 0x80) >> 7) == 1)//最高位为1，表示后续字节为该值的一部分
                {
                    lstFieldValue.add(value);
                    offset++;
                    value = byteArray[offset];
                }
                //最后一个字节
                lstFieldValue.add(byteArray[offset]);
                offset += 1;
                //返回值
                int iFieldValue = 0;
                for (int k = lstFieldValue.size() - 1; k >= 0; k--) {
                    iFieldValue += (lstFieldValue.get(k) & 0x7F) << (k * 7);
                }
                int key = (iFieldValue & 0xFFFFF8) >> 3;
                int mapValue = byteArray[offset];
                offset += 1;
                paramMap.put(key, mapValue);
            }
            object.setParamList(paramMap);
            objectList.add(object);
        }
        pack.setObjectList(objectList);
        return pack;
    }


    public static byte[] convertIntToCShapByteArray(int i) {
        byte[] a = new byte[4];
        a[3] = (byte) (0xff & i);
        a[2] = (byte) ((0xff00 & i) >> 8);
        a[1] = (byte) ((0xff0000 & i) >> 16);
        a[0] = (byte) ((0xff000000 & i) >> 24);
        return a;
    }

    /**
     * 将int数值转换为占四个字节的byte数组，本方法适用于(高位在前，低位在后)的顺序。  和bytesToInt2（）配套使用
     */
    /**
     * byte数组中取int数值，本方法适用于(低位在前，高位在后)的顺序，和和intToBytes（）配套使用
     *
     * @param src    byte数组
     * @param offset 从数组的第offset位开始
     * @return int数值
     */
    public static int convertCShapbytesToInt(byte[] src, int offset) {
        int value;
        value = (int) ((src[offset + 3] & 0xFF)
                | ((src[offset + 2] & 0xFF) << 8)
                | ((src[offset + 1] & 0xFF) << 16)
                | ((src[offset] & 0xFF) << 24));
        return value;
    }

    public static byte[] convertParamIdToByteArray(int paramId) {
        paramId = paramId << 3;
        List<Byte> lstVal = new ArrayList<>();
        if (paramId == 0) {
            lstVal.add((byte) 0);
        } else {
            while (paramId > 0) {
                byte byt8 = (byte) (paramId & 0x7F);
                paramId = paramId >> 7;
                if (paramId > 0) {
                    byt8 = (byte) (byt8 | 0x80);
                }
                lstVal.add(byt8);
            }
        }
        byte data[] = new byte[lstVal.size()];
        for (int i = 0; i < data.length; i++) {
            data[i] = lstVal.get(i);
        }
        return data;
    }

    public static String byteArrayToHexString(byte[] data) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < data.length; i++) {
            sb.append(Integer.toHexString(data[i]));
        }
        return sb.toString().toUpperCase();
    }
}
